/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dale2507.gates.gate;

import dale2507.gates.GatePlugin;
import dale2507.gates.Messenger;
import dale2507.gates.data.Settings;
import dale2507.gates.events.GateStatusChangeEvent;
import dale2507.gates.exceptions.VerificationException;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;

/**
 * Represents the Dialing chest
 * @author Dale2507
 */
public class DHD implements Listener {
    
    private static final int TORCH_TYPE_POSITION = 18;
    private static final int IRIS_KEY_POSITION = 19;
    private static final int INDEFINATE_ITEM_POSITION = 26;
    
    private Gate gate;
    private Block block;
    
    /**
     * Creates a DHD gate component from a chest block
     * @param block The chest block to create the gate component from
     * @throws VerificationException Thrown if the block given doesn't contain a chest
     */
    public DHD(Block block) throws VerificationException {
        this.block = block;
        if (!(this.block.getState() instanceof Chest))
            throw new VerificationException("Display block does not contain a sign.");
    }
    
    private Chest getChest() {
        return (Chest) this.getBlock().getState();
    }
    
    void setGate(Gate gate) {
        this.gate = gate;
            
        PluginManager pm = Bukkit.getServer().getPluginManager();
        pm.registerEvents(this, GatePlugin.getInstance());
    }
    
    public Gate getGate() {
        return this.gate;
    }

    /**
     * Gets the block used to by the DHD
     * @return The block used by the DHD
     */
    public Block getBlock() {
        return block;
    }
    
    /**
     * Get the address contained within the chest
     * @return 
     */
    public Address getAddress() {
        Address a = new Address();
        for (int x=0; x<9; x++) {
            ItemStack is = this.getChest().getBlockInventory().getItem(x);
            if (is != null) {
                AddressItem i = new AddressItem(is);
                a.setAddress(x, i);
            }
        }
        
        if (a.isEmpty()) return null;
        return a;
    }
    
    /**
     * Gets the autodial address contained within the chest
     * @return 
     */
    Address getAutoDialAddress() {
        Address a = new Address();
        for (int x=0; x<9; x++) {
            if (this.getChest().getBlockInventory().getItem(x+9) != null) {
                AddressItem i = new AddressItem(this.getChest().getBlockInventory().getItem(x+9));
                a.setAddress(x, i);
            }
        }
        
        if (a.isEmpty()) return null;
        return a;
    }
    
    /**
     * Gets the material to be used for the torch type
     * @return Torch type material
     */
    Material getTorchType() {
        ItemStack is = this.getChest().getBlockInventory().getItem(TORCH_TYPE_POSITION);
        if (is == null) return null;
        if (is.getType().equals(Material.TORCH) || is.getType().equals(Material.REDSTONE_TORCH_ON)) return is.getType();
        return null;
    }
    
    /**
     * Gets the material to be used for the iris key
     * @return Iris key material
     */
    Material getIrisKey() {
        if (this.getChest().getBlockInventory().getItem(IRIS_KEY_POSITION) == null) return null;
        return this.getChest().getBlockInventory().getItem(IRIS_KEY_POSITION).getType();
    }
    
    boolean isIndefinite() {
        ItemStack is = this.getChest().getBlockInventory().getItem(DHD.INDEFINATE_ITEM_POSITION);
        if (is == null || !is.getType().equals(Settings.getInstance().creation.indefiniteConnectionItem())) return false;
        return true;
    }

    void empty() {
        this.getChest().getBlockInventory().clear();
    }
    
    @EventHandler(priority = EventPriority.HIGH)
    public void onGateStatusChange(GateStatusChangeEvent event) {
        if (event.getGate().equals(this.getGate()) && event.getNewStatus() == Gate.Status.OUTGOING) {
            this.empty();
        }
    }
    
    @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
    public void onDisplayDestroyed(BlockBreakEvent event) {
        if (event.getBlock().equals(this.getBlock())) {
            event.setCancelled(true);
            if (event.getPlayer() != null) Messenger.sendMessage(event.getPlayer(), Messenger.ERROR, "The gate display must be destroyed first");
        }
    }

    void removeListeners() {
        HandlerList.unregisterAll(this);
    }
    
}
